package com.example.nettydemo.handle;

import com.alibaba.fastjson.JSONObject;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.pool.*;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.FutureListener;
import io.netty.util.concurrent.Promise;
import lombok.extern.log4j.Log4j;
import lombok.extern.log4j.Log4j2;
import lombok.extern.slf4j.Slf4j;

import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * liushuai
 *
 * @author liushuai
 * @date 2020-08-25 13:11
 */
@Slf4j
public class NettyClientPool {
    private Bootstrap bootstrap;
    private NioEventLoopGroup nioEventLoopGroup;

    public static ChannelPoolMap<SocketAddress, SimpleChannelPool> poolMap;

    public NettyClientPool(String host, Integer port) {
        this();
        bootstrap.remoteAddress(host, port);
    }

    public NettyClientPool() {
        bootstrap = new Bootstrap();
        nioEventLoopGroup = new NioEventLoopGroup();

        bootstrap.group(nioEventLoopGroup);
        bootstrap.channel(NioSocketChannel.class);

        initChannelPool();
    }

    public void initChannelPool() {
        poolMap = new AbstractChannelPoolMap<SocketAddress, SimpleChannelPool>() {
            @Override
            protected SimpleChannelPool newPool(SocketAddress key) {
                return new FixedChannelPool(bootstrap.remoteAddress(key), new NettyChannelPoolHandler(), 5);
            }
        };
    }

    public InetSocketAddress createKey(String host, int port) {
        return new InetSocketAddress(host, port);
    }

    public void send(Integer i) throws InterruptedException {
        //从连接池中获取连接
        SimpleChannelPool pool = poolMap.get(createKey("localhost", 9888));

        //申请连接，没有申请到或者网络断开，返回null
        Future<Channel> future = pool.acquire().sync();

        future.addListener(new FutureListener<Channel>() {
            @Override
            public void operationComplete(Future<Channel> future) throws Exception {
                if (future.isSuccess()) {
                    //给服务端发送数据
                    Channel channel = future.getNow();

                    String str="{\n" +
                            // "  \"type\": \"service/heartbeat/resend\",\n" +
                            "  \"type\": \"service\",\n" +
                            "  \"image\": {\n" +
                            "    \"type\": \"base64\",\n" +
                            "    \"data\": \"iVBORw0KGgoAAAANSUhEUgAAANIAAAAiCAYAAAAqC4dbAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAACEhSURBVHhe7VwHfFTF1v/vZjfZ9A4kBAhFQBFUEEUUVBAf0lVAEVEUEbsoReVDgSeCKE0RC00RQeVZsFcEQQFRSkAgJAESQgghpCe72Wz7zn82A0sMISDvp75fjt7ce+fOPefMmVPnzmJo0aKFB3VQB3Xwp8BYea6DOqiDPwF/2pAYzvRRGzjT/nVQB/8E+FOGRGMwyB99nM44vP3dcnjU2VNnTv948Mhc6kOD73V1UN07BN923+OfADUaUo2D8WmiEdUGaEAeg1EOgzrLHy+eyvdrpFcJp+vj+7xqP9/r6uB0z88WNF7Njy+dqjSr6/Nn4VT4qrZV16+mNh4GmUt9+Lb59uHh+x6f+4JvH4K+r9rme/67QY2LDdUxrYVEUbjljxKJdBNRyun0g3QbK41HwAi390LAI0Z1sngJf2zzpaF5qS2crn9Nz/Xkn45edf10my/o59U984Xq8Hhl4JUNn7PdF59uI/he+8KJdiqst61qP1/c+kzQ/fS90ej1x263dz6r4lHgZVmBL67q4FTPffmolsZfCKc0JM2s0+k8zjQF5XK5YDKZ1L1HjIJPjPK3oqICZrP5uADYz8/PzztwSlH+p8DdsKv+BLcYj0twGk1+qs1A03J7pN0t70qLPCc+p5O4TPA4hb5g4LXJZIDD4VQ0SIvgSzsgIEDxS/r64L0el+KlcuI1sI3PrVarwsF+wcHB6hnb9XO2a1oOh0ONm6DbiZd86WvNH9uIg/d8h+9qnDxT1uxD0PjZrvkU9LBXWBHoHyzP5cbolmeVfVwyVjlT2m5FV+aJMqPgpZU4jMSt8HoUD+zjoTcUmZr9/QU/58s7zxwLD7vdDovFgry8PAQFBSm5EjS/PLMf3+FB/vkOx8dnirr88Yit8cz5VnIQOmSFB+faQVwkXgkaF4GyIL/kg9ek93eDGiMSBdWkSROEhoaiqKgIYWFhiImJQWFhIYqLi9VgOTjeCx4lbP1edHQ0jh07hgBLAFxiGJGhEdi5dzsSmjVGRVE5nCLVUpMN9SJDUZwrim8QhePEOewIFTqOEivKRXgOpw3R8THILMtA8xbNECr0rOlubNuahBuuuQEZB9NRv34DlJeXIyQkRNHu1KkTPvroI0RFRSEnJ0cpAPmnsbOPzWZT/cg7+ST/9erVQ2lpqWrv06cPzj//fIVzzpw56n3KIDk5GU2bNlV4OLGc1PPOOw8pKSnwF0XkfVlZmfBTX8lH4yMunrOyspSCkebWrVsVn9nZ2eod8tW4cWPVzveJi/yRB4NBDNFlQkGZA9dc2wfrV3+E8DBxQrAgMCgQ2VnZaNK4GYpLCmVOnGJULjRqlICszCMoLbdK3xBECM201DTUi4mCzQG5T0SD2ATUj0+A016O7b+uRYUzDyUlpUpuXkNzIyIiAq1bt8aQIUPw7rvv4scff0RsbCz27t2r2g8ePKgcD8dE/g8cOICbb74Z69evx9GjRxEZGYkKewWstlJ4bHa0ansxtif9hnqCw+Uxi9xMSE1NQacrOuNwVqYyPtKm3hG3chLCB/WOtGnIf0djqtGQOKBGjRphz5496NGjBx566CFlLHfffTe6d++ujIcCKykpUYJkPw6Qg09PT0dCQoLySEY/AxLiGsLmtsJudcBeUo4iWwmeWPQ4zBY/PHvbdESGRaPCZUdsXDQCgi04mH0Q53VpgUbyXu9BPdGoTUNs3bwVkZb6mDduPo4ezkWz+i2wc8cO9O3bV03ikiVL8N5772HGjBnYuHEjLrroIqXMqampWLx4MZo3b64MhpNBxc/IyMCll16Kjh07KmXgfcuWLdWETZkyBZMmTVKKRCPixFKpaXSMJJTLrl27UFBQoMZJ78kJjo+PVw5n8+bNeP3113HrrbcqWezcuVPxSaO84IILVF8C5fbtt98iMDAQV199NWbOnInLLrtMKTP7EZL37EZeYQWeemYxrryqr4znF4wfMwQWk1MMMFDoN4DNWoz0jEI0b90W6QdSMPzuh/DGK3Mx99WlGHV7b1zTpSMKSktw8NBBxDe5CFNnrpR++diw6TNc13UAFr0+Bnt/XyNz2lIpbmZmpuLxu+++U46Ajmnq1KnKMXGMlN+hQ4fwwgsvKMfDyP3SSy9h9OjRWLlypTKi+fPni5waY8OvG/BIn5tx+x13YOSDD2CWjLFbv34IDA1DhBh2WEQ4GkTFiKPdo7IdyvfCCy9U8tWGxPvdu3crun9HOO2qHQfBSb7lllvw9ddfK0WlEY0dOxYjRoxQBsZQzgFTCDyoBIQuXbooz6iMS4VpD/wkjWOCBn8PcoqzENokXEK6CyViWHzuMppQVuFG32G98NobryCsfijGPDAOuYXH8POajVg4503Yj0lKBLPgMqnocMMNN+CJJ55QhnDFFVcohSeQrvZe9Pzvv/8+PvvsM6XoHAMjAg2Lz2kIPOhBCVR4Ap0Jo4jGxXHSuL766it07twZW7ZsUZGGEUelLPJc9yFP1157rZJRXFycMhQaDp8TF2W1evVqDBo0SNGjcbZq1Up5X7/KPvS7xRJV+g18QEXDwYPa41B2AVZ9moJL2ndDcYFdJskMl8OF81p2wuhxc0QuCWh2fg80SeyA0Ii26NprGJweCwwyFn+zCceO5iNrfwZKCjJhMkYiJMiFPTt/9aZOQk+PgcbBiEu5UqYDBw70zmUlb3QwTz31lOpHB0DD+eWXX1Tk1nL3yADqBQbjueemY8L/jcfEe0agocWIGU8+gXX/WYkoSxCcbgcMUi1o/dFypNxpOGwjrv8mkF99nA2c1pAIHFSDBg2UUtCAKFxOOEM9vTYNjQZHZaJi80zg8wH9+6NM0gWmG1ytszmLEdMqWtKrchGSRcL5UZQWWfHg7AcR2SYSbkkzwgIC8cbUJVj3y3osm/ceHn9iPL768HvkFRXjLvHEhY48YVwG7fTWTzNnzlJK0Lt3b8UHgZFFGzgnhBPOyWY0feSRR1TEoEHRUDhJOpWhIvD6mmuuwb333qvGxjFpvBwbhU2jpOdlpGK0GTx4sEof9WTQqxLvpk2bsG3bNixfvhxJSUmKH+IibzQs0lqwYIGKdFQg8sqUJvtIljyD0HagabPLccvgu7Di/bfx5IQ5iIsNw5yX/g//nvEWps9ert6NrNcct42YCJgb4ZVFnyAqNBHPTFsk6V45BvS7A1HxklLDITWRB3nZqdLPgHpRjTD41qFY+tYyWB3FktoJz1I3sY7h/DBFY3pOx3jxxRdjwIABSgeYinKMlMXs2bPVeKgXjL5MS5mhEIdd0kxHYRFmPjYWTnGE+w4ewtU9euHbteuxPy0Zn4pjLiwvFUMxw+7yykynzcTNex68Jg1tTGer7KcC4iNufZwNfj8R0uTK6z8Amaey0XNfcsklSEtLU16R+fzatWuV16UiMQ3Q7fTwDRs2VF62Xbt28uwQmjVrJulAQxwW5YhqGoGlXy7CV998g07dL4OfRKYta7ZiyISBiImLQsqvqYI3Cv4R/ugx+Drs2LwLPftfh4ysdEnV2iE8IgxZSdkqtWvTqh3Gjx8n+fstQjMBQ4cOVYKgUnPiN2zYoITC1IsKSsVnWtKrVy9lIPv27UNiYqJSakYMKgzfZX2jx33PPffgp59+UjiYrjDNYfSgQjG60HjDw8MxfPjw4zk8awi2URbESwOjPGi8xMPj8OHDKh398MMPVSRas2YNunXrpvozql7aoRNCw6X4d0dgzJhpmP78GDQWXm/ofSeWv70AuZkbsH3LBqQdSIKtNA/xMn6YYxEdGYN335yDeiLLtavXwe3JxPK3JiIu2iLRqwyNEpuJsrdE56tvxIp3XoJJPP7AgUMlxWqOksLDEgk9iI2JlTEG4vHHH1cO6csvv1S1G2U6b948JYMjR46o1LlDhw5qrJT1p59+irvuukul0k2FV74TKc9iIiMQGRKMrXt3Y4Okqe3bdsCRHEkr9yZLKh+LvGMF6NjuYqmZPIiOiVZyI11GIjpwypPn/fv3qzaCNqpzBRqfNqozhRojEhHS+1D5fv75Z6VAw4YNU6kUPSufM4+lx6Bg6Xl//fVXle4Qfv/9d+yQGmbDRpnwtFSYxOMeyjkCqZSQdiwN7nAjwuuF4Lp7e8M/1ohD6QdRXlQudU0xkrclI1CiTHb2YVWokh5zcgoyRYpTs79ZcKZI/XFApRI//LBa1ToEKrNOObmwQCWlt6SnY7rF+mncuHEq/8/Pz1cOg3UM+zJ9YYShg+DEtW3bVqU2dBakzWdMx2iIjBx33nmnuma04ViZArGO5NhZM/JM3DRSKhbzfC5O8B3KlCkn6XB87Meai8/X/vg9CvKtMJk9uHdUX+xP3iCezYkyK0RZR2DP7u3YtulbJG1cjVCJ4Af2bMN/3puLmCgTVn30BhonxOOSds2wauXbyD5wCPk5RXAbnFj7828Ydvf9eHvZArRo1ggtm7fCgw/cho4XtcUDDz4nTsQmDiNH8cZ5/+KLL5RDpAxo8OSVhkJdWLdunXISVHw1L8L39ddfr64ph4JjebB7XBg7bbo4hTBc2vp8xEZFIm3HNtFYO9549jmJVGWSpBuwQ+TStl1bdJT6kHIiDeqWPlibaQU/G0WvCYiPBnS2RkQ4pSFppFSuO6RIZG3EdI6KRA9Nz0MvRKNhSkJlpPLddtttePLJJxUOeihGgdlz5oixMa0wIiQ4hNUNftvxE85rlYjyfAfCogPRJLQZ9u3IkHQvAE7J9/sN/ReiIkNRdLAU33z2PXr2vloingWff/QFgsyhwpsJYeGhalGgvNyORYsWH1+qZjRhtOSE0piYonFR4aqrrlKejpGVxsYCesKECcfTCY6XaSujEg2HdSGjLHFoYD9Gofbt26uIxbqAUYv1I+kTB+WhDxoVa0VGMxqPbieQP/Jx++23q0Keizl0Buy7efMv4lCssJYXIMjC1dFA/LR+C0JDgEcfewTBodESzaUutZjhMLjhZ/FH4ZH98LcEY8DQh/H1N59h67at6Nd/EPyDw+D0k3St3I37R47Fq/NnwOzMw4GMLBWB/E3FeGhkdzz2cD8EBZthtdqkpnkOr776qlJgzq2uHck7jZ76QTmzH2XCqEHZMTVmH6aJ3r4mWAID0CA8BjtS98Ik8omJjUZgXAxeWrhQUjo33JSJ1M6UVS9x0sRH2fgepPnfBM7b2RoR4ZTcESkHRK/04osvKo/EyWY6cuONN+Lzzz9Xiw0UNr0PV8dYe3C5mOkS6yMqIwvxiPAIGA1SwPoZYcsux8QHpqBv+5sxOHEY3hrzHt4etwLDOo7Cnu9SEGC0qDQsac0uDGk7HGF+4WiV2Brznn4bm1ZtVEbqCpAazOPgRwlVG3HJ9eOPPz6uoNowONlsY8TiyhLHMnLkSLVKRiVg3USHQAXnit7EiRPVuDleprKMEHQEkydPVh6YOJmzM5pxjHyXUYhjX7ZsmZpw7dnYl4rxjaSwNMhHH31U0WE7D9Kh3BgpuZrHvvTE9913n3IOCxcuFqciRbYoULnVKWldayx8cykKS8vw5jufYtb8VThabIXLwe98Ig63AQGmCsye8Ri6d+qGFqLUcQ3jUVwmNavUPdIDAWJ0K99/FfvStqFxfJRE5k8BqY3KrcXCm0RyMUyuNoSKtdIwON+MpDSknj17KtmSZ+1kOW4uulAXRo0apXTkyiuvVNdbtm5RC0ysNqQ39uRkY62ML2XfAQy6ZSi+W70Gyz9bhYxjOSpTMXsMSgYvv/yymn/SZKZDWfFMmhp8r/8ucNrlb+bs9LQcHAfElRoOkl6TA2I70z/WQUxT6L3pPVg/sNZQgpQCt1F8HJJ2/45GrRuiML8QQaZAuE1ORElOnJ+bL2mLdBSBltrKEBpMpRVP6ZYUwa9C8uZIHM44Cofbjs59L0XG1sPYtWUnune+HkfzctXSNT07azNGiRUrVijFZxs9KnmmklMJGFX5DYSrQVQGtrMPx8kxMd9nscw6hg6D/ReK52QK89tvv6k0h+kg32Uf1gmMbKRHo2VqRiXUCxRUREY1pj06YvLMVJDL3HQC5IX9yT9TZO0QiNNmsyLYEoJS8RuRUQkwSnp39EgO/M0GSW/t4u0DlQKzRi232mF3lkv6VyKpXSKOZOWKkkq/QIne4jhSUlKlvSGcngqU280I9DdIFtEayam7ERTgVtu2WK8w+pRJDsk6ifLQUZk0mI1wTJQhl+fpbMgveeW4ORc33XQTFi1ZDD/BFxzEMRtgLS1EgOCrHxOPrH2S5odaYJCU1GLyR+ruPeh4RSccyjokOgUlDy5aUJ84P3yfvDDaUd+0IZ85aFU/8e7Z4zoZajQkKoI+CNV5ArZx4HqVivf60OGYX6w9gsMUwK/5ThjF+7iNLsnZjd4v3fyiTtx+EkFggp/TiAr5DybB4fKDQyaeCuEwiKcqt8Lfz6JSGle5RCaRgaZLwycfjFIaOMk6ArAPn3MyNLCN95p/DXQaVB6+q1MyGiYVXvfT9NjONh4cM9s1aG9KGfGsgTSJn3jZznfZVxsRwYuTq3yCgwNVeGUuRE7chWAUefAdL1+SfhpEXgiSvuLJpQbxk7RKCYgbhIW02WyCs0LeN1JuUplIFHO5yyRySDiSPjIx6h1Ot5enE/xr/khLj8d3zgn6zHHxQzyzEOou2z2Ci3rgpCoJnyZ5JL4SknEKLnHGwr9J7aw4sQOFOx4IvGe7ps3rMwMvX0oWCqif3itf/s8c7wmo0ZB8CVQdwKkGpNt9zzqn/gNIkwzpBB65NxhFkDKp3B6kQE7ed6lUcvJeHj9rOjXBqfrods3b6fBoOJP3qATV5fd8t6pcNM6qbRrY7r3X8vW2a/C+T01Vd5XnE6DfEUkqufv20bQ1aOX1pU/Q97rvCZ5Ohqr4CPpe4T3Ogy/wnrh4pkPhWJTlVR4n09PXVekQdLu3r1emdErEQxlVxaGvCSe/Wzuo0ZAIGuGpiPg+PxXhqu9WBd/2qrjYyj1a3iv5K+18UhO9mqA6XmrCcxIvldfVvVe1X1Wo+h6vfSMlj6oGVzW6VYeDZx5a8Qm6XQMV1is1Pju5n2BS9/od0iSuqqAdAvtpPjXNqvQ0qD10qobz0iAnmp6mQVz6XjsBg5pwZg3eNj43Gk9kFoTqaPJe45IObJBWLS/ttPied4zs622rHh+zg6ptp4LTGhLhVILScLrnZwJVcZE5ryF5QQWqyj7nkm5NQDqEc0WLCsF6gikoJ5QpEmsB1hekxRqKqRPrJ9aeTJV4sE7TNSrrFioh2/ke6xbWqsRDvMRJXNz9IeqAI1L/RUdHSRpngsMuzyRVDjSZ1eoaFwWU8kot660X41VWwBVbHgTWg1xcoHJxUYA1EemQPlM+8qIXU8gna2R+rvB+pyuXmswBu6Rv0RERKCgqlDEGSbruLzyXCp9uGVeYSv+dLrekqeTJjUCpoUTq8JOUNPNgpqohPR5xLB4xBI9TUlVveumS1NdfcDmENmvUevVi5dqBslK7koHJL0BoO6RONMu1SfoUqt0j5FcD5c20XQPlyBXq2hrTH3OOauB0iM6lMlfFxTsajz54r/ucS7o1AemcS1qcXE4kv8nQWAhc7eK3r4cfflh9n+JuBRoNFZTfVLjiqD96ckWUq4V8l8v8VDB+r+LqHxWAyk/lpsJzMYDf5xL4wVamOzk1GfGioAapNS1OUZwyK9IPHMS+/emiaKEIDwtHZsYhpOzdq3ZecP/cDz/8oD4TkAZpcjGCNR75pKF37dpVrXRS8Whs69b9KGM7IMYUC5vVhoyMbLTvNBATJi1DQbEZox+fhzJ7KHKPlkrdY0aDeMriAA4Kn1m5hXj5lbVo0bo7kpJScSgjHUdzcxAr8goOtCB1Xwp27U4Tfg/AYAqTc7YYREOkpuxHeLjwHx6BfWnpKCxyY9jdUzB6/Mu458GpePrfi+EySH/hn7JkvUUZ8rse+aYRcQGI3/54T+fkW6+eDmplSH81KOOpPP5XgFGFq4hcFuc2Im605VI4V8a4YsXnNDidgnA5npPLvYJcSWMbJ5rPGQVocFw+5zet3Nxc9eH56aefRpEYJKNPhaMCbjGucIk8H77/Ljq3Ph9jR4zA0Ou7wSJ4o80BEg24sCD0pE5VS9dCn9/LqGQ0TPJLmqTHg1GJRs1PHjQ29uVKbVRUtDznzzkcglMSS1Mwrut5K4rKAnDDjcPR8sKueODBCRI1yoR/cSxOpm4GFJW78P67SViy/DU8NmYGho96Gjn5ZdJBaEoEqnC6EBqRgMnTXoMlpBFGj3sRDgRj+sxlOJyTrb4/kn+mgeERDZDYvB3cpghs3LIdEdFxEqEoJ6/MeNAZ0PHwIOhrHjrlrC38IwzpfxU4WVR27p7gxFIR+b2LkUSnZjyotFRkLrvz4y6/TWll4HP25a6D/v37q90GWtn5cXfIkNtgtXOHhBFWSalmTZiEX779Ch9++Tm6d70eN93QB6s//ADfrngbxSVMs7xGzojI1I3Rh0ZCGvyswLRNGzG9N3eNcJsTv5Vxbx7HQHBV/q7MZrPjmQmzJM3LkCjgQuOENigqLcNrrz6PsgJuVJYUXY5cST1nz1uJ9z9YiNLcdNw+9F+4574HMeeVLyR6UdH9Jbo5cUGbLohLaI9rrx8ImzMIj4+bKQZqwLfrDiIyojFc6rdrkIi6RRxHBQryStH5sm74ef3XyM5KQoDBX+h55ep7aHlSbvp8JlBnSH8B6Mnj3sDx48erSEJDYRuNhCkf0zSmaEzv+A2IO0v4vYj79bhPjx/DGRGYGlmtpZg58wX07MntOUZ5J1ilfKy18vPzEB0eA7vUQokN49D1sg6Ii2+I67r3wOQXn8Nbn36IUWPH4mJ5t16DBqJiRqkX/DBt+jS1a4Hbc7y1iQcffPCBqu3oABidmGZyzyENlv2YrrLWIMRKjeSR2qVBfCSef/EZdLmyCyz+Efjk42UIkPpn4tPz0bzNpWJHJqX8PW+8H62bX4jX5k/GvQ89gfNbNMGQQd3QqmVLTJ00UwwiFx0uuwpTp82VVC4WPboPRoXdCafk+6l7d2DW89yhUgKjjD8iIkRqIanZ/INRUnIIAf5RMrYmMJtiEGAxqmX5oKAQSRfrK9nSYbDG5FYnfegP0bWFOkP6i4CKSO/N3RHcAEylZf3BiENvyIMKy4/D9PTM3/lxmBtb2UZj8npOSNSIFsPrL/l+sjo4/1SOZ555Rn1A5eoXP45WSCS5ut8AVMhLO5J24vPvVmO4RCy3FObjHn4Edqlv+K3HJMX9a6++pvjkYgH32/HDM38TxMhEYKHOdJTGxd0uNHrWTFzwIEgGpVKyEqlVpkyaivfeWQKbKPqESdOxYP40fPLJG7j1llGIiowRpQ/CTb17Y/DgKxAdGYi83DxJCR2wlmbilkEdMP35xxARFYLfd/2Ku26/GXDkY/QjfREXHYmWjesjeddP2JO0Bk63VQzTjfyiMvS7aThy8g4jPfV3xMUFoMxmxPc/7sEF7a9TBkjHUCYOiFvHnn32WcU3U1iOjwflX5fa/c2BE8SJ5J4/bpylMhKYNhGYNrEQZq7OCX3nnXfUedasWapQZqThNie7nRNPoyNOrvrZMWXKVEnLSpRStGjRQimKTYyWu0tyJHXzj4lE3tFsvLtkIWIbxcNhs4pi2TDm3vtQXmoVhTAgIz1d/eyD9RbriDZt2qhdBlwpJI869eH2r8svv1xtcGV6x61UrPcIXoPzoGliC7y2cC6WLJ6K/yydC7utDOZAI75ctQj/nnw3juVnwmW0YvTDwyCxFRXWMrUKZ7dLeijjCRH6RoNTNNWkksDco7uRkBCHnMxDUp8txcxZz2PFu2/JOyb1S9yKCgMSGl+ISy7qgAULnkdYaDRMbjtemTMGTz11PxIaNpF6y6BWEfkjR+7KZ8pKB8UVS6768eA46chqC3WG9BcBPToNhMDz9u3b1e+laGDco8jVJL37gbvq586dq7Yqcec6DY9KXVhYIAbEOskpxmWRqNRL7j0S2dKUYnAvIdOvmTNfhK1YjEjqnxBLEFqed4FEpj5oGhyKRi0vhNXpRrOrusBfcNocNvSR6EYjp7EyVeNKHFMgRkIaOXlkKsotTnzOFUeu8HEljGkgQa16mczYf2A79qduRtt2HXBVt37qd2k5OUVo0LAVAoP8JVJyC7MZoWEBknpJLWQ00/6kvUL+SApsdIoBiTF5jGo3xLG8o/g9OQmbtudjyPC78PqSFdi+bScCJFWDGBx3yLRsmoDxY0fims5dsXXLd7AEhiEuNgrbNq3CyuXzEGiRMbgdCA0OUQ6DizyrVq1SqTLHx4NGVJfa/QOA0YZGwo2y/OZCD87Nn/x3ELj4wDydUYWbRfXyMlf0mEbR6Ghs3DCqU0Ae/J1Vz57/Uu+wlqFi0OBGjrwXEZGR6le3GUeOYpwYbInBDwnt2uKO++5BZnEByvgtRgyX0ZKrdtx4ymvWZVxFZHTjTn+2kRaNnMbGKMQIydU7pnc09KVLl0o/US5JJ83mADgq3Li+Zy8kNklE8p4U3DxoiIypu0QQ7xYj4nNIDccfaQp15GSnYKekcdwG5eLucFFo4hNLQXhoECaOH4oH7umF2dMfxqB+l+PyDm1gt/KHkYFizP5SZ65CZEQAftu8Wvjfg9S0zcg8mCa1kkWlrfxQzFVC0uWufW5kphNguk2Zc17oLPi8tlCrD7J1cG6BikHjYR3DCeM9FZNGoQ2D9/wGRA/P52zjM/1RlBFNf2uiAnN1jQrA9zRQSfkvCrE+4kbX2HqxbIVNlNYiCuV2cUnZIbiC1VY71lLcuEveaOikyzSHOKlgNEpNl236gyzbSIv8sdZgtGKxzg+y/GmNy+FGidWGcocdFn/u3+NP3oMlMnBTLlNFj/cDs9RUbomoXOkLCDQpL0++yEvW4Sy1sZg8ko7HRRkZ4JAxqD198r/baUBBYb5yQlzo8P7rU4Eoq7Ah0CyRxiiqLhEv79gxlSJzcYRjJJB/zoXvNdNUjpP3p4M6Q/oLgJOkj6rgO6HaeHw9o+977KsnmW2+7xJ8FYDXLrfgkv/cgs6Py9OSQ6l/gou5lPzPe9KiclXFRdBtGm9VmlWfE/hIKFfeiXFIfcL002UQYyB9tafOi0seqGvyw/9oHaql8tkJ3HLItfd9ueSujMo2L//ee3Ej0oP/3gN3Q9BgjF6s0ofGTtC8VwdMW6uO51RQZ0h/EegJqmkiCbXtQ6gVLiqfdOOeRaVV3j/UO6V6teGrNjwRjvcjLYK69l6qbSrei8rzyaB48XlWM0329mLykqp8U9HQ73jpeVtqZxxaFrWBOkOqgzo4B3AiZ6iDOqiDs4Y6Q6qDOvjTAPw/CLdpRHS4VRwAAAAASUVORK5CYII=\",\n" +
                            "    \"dataMd5Hash\": \"f35c80ba3b483798db09e9d6da2cfdf7\",\n" +
                            "    \"properties\": {\n" +
                            "      \"path\": \"/opt/ftp/images/a.png\",\n" +
                            "      \"cameraId\": 1,\n" +
                            "      \"*\": \"*\"\n" +
                            "    }\n" +
                            "  },\n" +
                            "  \"calibrations\": [\n" +
                            "    {\n" +
                            "      \"id\": 256,\n" +
                            "      \"calibration\": [\n" +
                            "        [\"point1_x\", \"point1_y\"],\n" +
                            "        [\"point2_x\", \"point2_y\"],\n" +
                            "        [\"point3_x\", \"point3_y\"],\n" +
                            "        [\"point4_x\", \"point4_y\"]\n" +
                            "      ],\n" +
                            "      \"properties\": {\n" +
                            "        \"spaceId\": 256,\n" +
                            "        \"*\": \"*\"\n" +
                            "      }\n" +
                            "    }\n" +
                            "  ],\n" +
                            "  \"beingUsed\": []\n" +
                            "}\n";
                    channel.writeAndFlush(JSONObject.parseObject(str).toJSONString().concat("JSONSENDOVER"));
                    log.debug("使用 channel.id(): {}", channel.id());

                    // 连接放回连接池，这里一定记得放回去
                    // pool.release(channel);
                } else {
                    log.error("future is not Success ");
                }
            }
        });
    }

    class NettyChannelPoolHandler implements ChannelPoolHandler {
        /**
         * 使用完channel需要释放才能放入连接池
         */
        @Override
        public void channelReleased(Channel ch) throws Exception {
            log.debug("channelReleased. Channel ID: {}", ch.id());
            ch.pipeline().addLast(new IdleStateHandler(0, 0, 3, TimeUnit.SECONDS));  //1
            ch.pipeline().addLast(new HeartBeatHandler());
            ch.pipeline().addLast(new NettyClientMessageHander());
        }

        /**
         * 获取连接池中的channel
         */
        @Override
        public void channelAcquired(Channel ch) throws Exception {
            log.debug("channelAcquired. Channel ID: {}", ch.id());
        }

        /**
         * 当链接创建的时候添加channelhandler，只有当channel不足时会创建，但不会超过限制的最大channel数
         */
        @Override
        public void channelCreated(Channel ch) throws Exception {
            log.debug("channelCreated. Channel ID: {}", ch.id());

            SocketChannel channel = (SocketChannel) ch;
            channel.config().setKeepAlive(true);
            channel.config().setTcpNoDelay(true);
            ch.pipeline().addLast(
                    new DelimiterBasedFrameDecoder(Integer.MAX_VALUE, Delimiters.lineDelimiter()[0]));
            ch.pipeline().addLast(new StringEncoder());
            ch.pipeline().addLast(new StringDecoder());
            // 绑定channel的handler
            ch.pipeline().addLast(new NettyClientMessageHander());
        }
    }

    // class NettyClientMessageHander extends ChannelInboundHandler<String> {
    class NettyClientMessageHander extends SimpleChannelInboundHandler<String> {
        private StringBuffer stringBuffer = new StringBuffer();
        @Override
        protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
            stringBuffer.append(msg);
        }

        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
            super.channelReadComplete(ctx);
            String body = stringBuffer.toString();
            stringBuffer.delete(0, stringBuffer.length());

            log.debug("Server return Message: {}", body);
            JSONObject jsonObject = JSONObject.parseObject(body.replace("JSONSENDOVER", ""));
            String type = jsonObject.getString("type");
            switch (type) {
                case "heartbeat":
                    log.debug("heartbeat:{}", body);
                    break;
                case "service":
                    Channel channel = ctx.channel();
                    log.debug("接收数据 channel.id(): {}", channel.id());
                    poolMap.get(channel.remoteAddress()).release(channel);
                    break;
                default:
            }
        }
    }

    class HeartBeatHandler extends ChannelInboundHandlerAdapter {
        @Override
        public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
            if (evt instanceof IdleStateEvent) {
                Channel channel = ctx.channel();

                channel.writeAndFlush("{\"type\": \"heartbeat\"}JSONSENDOVER");
                log.debug("发送心跳: {},{}", channel.id(), channel.isWritable());
            } else {
                super.userEventTriggered(ctx, evt);
            }
        }
    }
}
